package cn.rokhdelar.ams.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.rokhdelar.ams.common.domain.po.Attachment;
import cn.rokhdelar.ams.common.domain.vo.AttachmentVO;
import cn.rokhdelar.ams.common.mapper.AttachmentMapper;
import cn.rokhdelar.ams.common.service.AttachmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Rokhdelar
 * @since 2025/3/14 -- 15:54
 **/
@Service
public class AttachmentServiceImpl extends ServiceImpl<AttachmentMapper, Attachment> implements AttachmentService {
    @Value("${attachment.upload-dir}")
    private String uploadDir;
    @Value("${attachment.url-prefix:}")
    private String urlPrefix;

    /**
     * 单个文件上传
     * @param file 文件对象
     * @param remark 备注
     * @return 附件对象
     */
    @Transactional
    @Override
    public AttachmentVO upload(MultipartFile file, String remark) {
        if (!file.isEmpty()) {
            Attachment attachment = saveFile(file, remark);
            return BeanUtil.copyProperties(attachment, AttachmentVO.class);
        } else {
            return null;
        }
    }

    /**
     * 批量文件上传
     * @param files 文件对象数组
     * @param remark 备注，可选，如果不提供则默认为空字符串。
     * @return 附件对象列表
     */
    @Transactional
    @Override
    public List<AttachmentVO> uploads(MultipartFile[] files, @Nullable String remark) {
        List<AttachmentVO> attachments = new ArrayList<>();
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                Attachment attachment = saveFile(file, remark);
                String relativeUrl = attachment.getRelativeUrl();
                attachment.setRelativeUrl(urlPrefix + relativeUrl);
                attachments.add(BeanUtil.copyProperties(attachment, AttachmentVO.class));
            }
        }
        return attachments;
    }

    /**
     * 下载文件接口
     *
     * @param id 文件ID
     * @return 文件资源对象
     */
    @Transactional
    @Override
    public Resource download(String id) {
        Attachment attachment = getById(id);
        if (attachment == null) {
            throw new RuntimeException("文件信息不存在，请检查文件ID是否正确。");
        }
        Path path = Paths.get(uploadDir+ File.separator + attachment.getSaveRelativePath()).normalize();
        try {
            UrlResource resource = new UrlResource(path.toUri());
            if (resource.exists() || resource.isReadable()) {
                return resource;
            } else {
                throw new RuntimeException("文件资源不存在或不可读。");
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Boolean delete(String id) {
        Attachment attachment = getById(id);
        boolean deleted = FileUtil.del(uploadDir+ File.separator + attachment.getSaveRelativePath());
        if (deleted) {
            return removeById(id);
        } else {
            throw new RuntimeException("文件删除失败，请检查文件是否存在或权限是否正确。");
        }
    }

    /**
     * 保存文件
     * @param file 文件对象
     * @return 文件的绝对路径
     */
    public Attachment saveFile(MultipartFile file, String remark) {
        String uploadDir = this.uploadDir + File.separator + DateUtil.format(new Date(), "yyyy-MM-dd");
        String saveFilename = FileNameUtil.mainName(file.getOriginalFilename())
                + '_'
                + System.currentTimeMillis()
                + '.'
                + FileNameUtil.extName(file.getOriginalFilename());
        FileUtil.mkdir(uploadDir);
        String fullPathFilename = uploadDir + File.separator + saveFilename;
        try {
            file.transferTo(new File(fullPathFilename));
        } catch (IOException e) {
            throw new RuntimeException("文件保存错误，请重试。");
        }

        // 保存文件信息到数据库
        Attachment attachment = new Attachment();
        attachment.setOriginalName(file.getOriginalFilename());
        attachment.setSaveRelativePath(File.separator + DateUtil.format(new Date(), "yyyy-MM-dd") + File.separator + saveFilename);
        attachment.setRelativeUrl(DateUtil.format(new Date(), "yyyy-MM-dd") + "/" + saveFilename);
        attachment.setFileExt(FileNameUtil.extName(file.getOriginalFilename()));
        attachment.setRemark(remark);
        save(attachment);
        return attachment;
    }

}
